# gozerbot/eventhandler.py
#
#

""" event handlers """

__copyright__ = 'this file is in the public domain'

from gozerbot.generic import handle_exception, rlog
from gozerbot.thr import start_new_thread
import Queue

class Eventhandler(object):

    """ events are handled in 3 queues with different priorities:
        high, normal and low. basic eventhandler handles bot ircevents
    """

    def __init__(self):
        self.sortedlist = []
        self.queues = {}
        for i in range(11):
            self.queues[i] = Queue.Queue()
            self.sortedlist.append(i)
        self.sortedlist.sort()
        self.go = Queue.Queue()
        self.stop = 0
        start_new_thread(self.handlethread, ())

    def put(self, speed=10, *args):
        """ put item on the queue """
        self.queues[speed].put_nowait(args)
        self.go.put('go')

    def getready(self):
        """ check queues from available data """
        ready = []
        for i in self.sortedlist:
            if self.queues[i].qsize():
                ready.append(i)
        return ready

    def handlethread(self):
        """ thread that polls the queues for items to dispatch """
        rlog(0, 'eventhandler', 'starting handle thread')
        while not self.stop:
            self.go.get()
            ready = self.getready()
            for i in ready:
                self.dispatch(self.queues[i])
        rlog(0, 'eventhandler', 'stopping')

    def dispatch(self, queue):
        """ dispatch functions from provided queue """
        try:
            (func, args, kwargs) = queue.get_nowait()
            func(*args, **kwargs)
        except Queue.Empty:
            return
        except:
            handle_exception()

class Irchandler(Eventhandler):

    """ handles ircevents """

    def dispatch(self, queue):
        """ dispatch ircevents from provided queue """
        try:
            (bot, ievent) = queue.get_nowait()
            bot.handle_ievent(ievent)
        except Queue.Empty:
            return
        except:
            handle_exception()

class Commandhandler(Eventhandler):

    """ handle bot commands """

    def dispatch(self, queue):
        """ dispatch bot commands from provided queue """
        try:
            (what, com, bot, ievent) = queue.get_nowait()
            what.dispatch(com, bot, ievent)
        except Queue.Empty:
            return
        except:
            handle_exception()

